#include "include.h"
#include "stdarg.h"	 	 
#include "stdio.h"	 	 
#include "string.h"	 
//////////////////////////////////////////////////////////////////////////////////	 
//作者：RIU									  
////////////////////////////////////////////////////////////////////////////////// 	   
/***************************************************************************************
		通信协议约定：
		USART2用于接收串口屏传输的信息
		串口屏有三个模式：数字键盘（0xa0），多级指令（0xa1），轨迹显示（0xa2）
		第一个帧头忽略！！
		一、数字键盘
			1、PID字符输入（0xb0）
				flag=1
				p0000:p后面加四位整形
				i0000
				d0000
			2、数字输入（0xb1）flag=2
		二、多级指令
			1、基本功能（0xb2）flag=3
			2、提高功能（0xb3）flag=4
		三、轨迹显示
			未定义
	***************************************************************************************/
//串口发送缓存区 	
__align(8) u8 USART3_TX_BUF[USART3_MAX_SEND_LEN]; 	//发送缓冲,最大USART3_MAX_SEND_LEN字节
#ifdef USART3_RX_EN   								//如果使能了接收   	  
//串口接收缓存区 	
u8 USART3_RX_BUF[USART3_MAX_RECV_LEN]; 				//接收缓冲,最大USART3_MAX_RECV_LEN个字节.


//通过判断接收连续2个字符之间的时间差不大于100ms来决定是不是一次连续的数据.
//如果2个字符接收间隔超过100ms,则认为不是1次连续数据.也就是超过100ms没有接收到
//任何数据,则表示此次接收完毕.
//接收到的数据状态
//[15]:0,没有接收到数据;1,接收到了一批数据.
//[14:0]:接收到的数据长度

//全局变量
u16 USART3_RX_STA=0;  
double sum_point, temp_point, num=0;
u8 Res;
u8 t, n, N, i, n_PID, mode, n_point;
u8 len, len_flash;	
u8 flag=0, flag_point=0;
u8 flash[200];  // 储存数组
u16 x=0, y=0, temp=0, sum=0;


//case1的核心功能函数，修改的全局变量在公用头文件里extern声明
void function_flag_1()
{
	armstart = 1;
	switch(USART3_RX_BUF[n])
	{
		//AB区抓取
		case 'L':
			L_state = num;
			break;
		case 'R':
			R_state = num;
			break;
		//C区向前抓取
		case 'F':
			F_state = num;
			break;
		//向前看
		case 'K':
			Look_state = num;
			break;
		//B区左右识别成熟度
		case 'A':
			L_GrapLook_state = num;
			break;
		case 'D':
			R_GrapLook_state = num;
			break;
		default:
			armstart = 0;
			break;
	}
	sum = 0;

}


//判断是否位小数	
void whether_point()
{
	for(t=0; n_PID<len; t++, n_PID++)
	{	
		flash[t] = USART3_RX_BUF[n_PID];
		if(USART3_RX_BUF[n_PID] == '.')
		{
				flag_point = 1;
				n_point = t;
		}
	}
}

//转存数据字符串为int或double
void deal_num()
{
	if(flag_point == 0)
	{
		for(t=0; t<len_flash; t++)
		{						
			temp = flash[t]-'0';
			for(i=1; i<len_flash-t; i++) //例如3位数乘2个10
			{		
				temp *= 10;		
			}
			sum += temp;
		}
		num = sum;
	}
	else if(flag_point == 1)
	{
		for(t=0; t<n_point; t++)
		{						
			temp = flash[t]-'0';
			for(i=1; i<n_point-t; i++) //例如3位数乘2个10
			{		
				temp *= 10;		
			}
			sum_point += temp;
		}
		for(t=n_point+1; t<len_flash; t++)
		{						
			temp_point = flash[t]-'0';
			for(i=0; i<t-n_point; i++) //例如1位小数乘1个0.1
			{		
				temp_point = 0.1 * temp_point;		
			}
			sum_point += temp_point;
		}
		num = sum_point;
	}
}



//判断信息模式
void judge_mode_of_message()
{
		for(t=0;t<len;t++)
		{
				 
			 if(USART3_RX_BUF[t]==0xb0)
			 {									
					flag=1;   //PID字符输入
					break;
			 }
			 else if(USART3_RX_BUF[t]==0xb1)
			 {	
					flag=2;   //速度输入
					break;
			 }					 
			 else if(USART3_RX_BUF[t]==0xb2)
			 {									
					flag=3;   //基本功能
					break;
			 }
			 else if(USART3_RX_BUF[t]==0xb3)
			 {	
					flag=4;   //提高功能
					break;
			 }
		}
}

//处理对应模式信息		
void deal_mode_of_message()
{
	switch(flag)
	{
		case 0:
//					printf("nothing\r\n");
			break;
		case 1:	
			//PID：例如(0xa0)(0xb0)p1234 
			//len=7 n_PID=3 
			n_PID=n+1;    //PID值位，整形

			flag_point = 0; //是否为小数标志初始化
			n_point = 0; //小数点位置初始化
			num = sum = 0; //整数总和初始化
			sum_point = 0.0; //小数总和初始化
		
			whether_point();	 //判断是否位小数	
		
			len_flash = t;
			n_PID = N;
		
			deal_num(); //转存数据字符串为int或double
			
			function_flag_1(); //	case1的核心功能函数
			
			break;
			
		case 2:
			//纯数字：(0xb1)
			for(t=0; n<len; t++, n++)
			{	
				flash[t] = USART3_RX_BUF[n];
				
				temp = USART3_RX_BUF[n]-'0';
				for(i=1; i<len-1-t; i++) //例如3位数乘2个10
				{		
					temp *= 10;		
				}
				sum += temp;
			}
			num = sum;
			sum = 0;
//					printf("num:%f\r\n", num);
			break;
			
		case 3:
			//多级指令基本功能（0xb2）
			for(t=0; n<len; t++, n++)
			{	
				flash[t] = USART3_RX_BUF[n];
				
				temp = USART3_RX_BUF[n]-'0';
				for(i=1; i<len-1-t; i++) //例如3位数乘2个10
				{		
					temp *= 10;		
				}
				sum += temp;
			}
			mode = sum;
			sum = 0;
//					printf("fundamental mode:%d\r\n", mode);
			break;
			
		case 4:
			//多级指令基本功能（0xa1）（0xb3）
			for(t=0; n<len; t++, n++)
			{	
				flash[t] = USART3_RX_BUF[n];
				
				temp = USART3_RX_BUF[n]-'0';
				for(i=1; i<len-1-t; i++) //例如3位数乘2个10
				{		
					temp *= 10;		
				}
				sum += temp;
			}
			mode = sum;
//					printf("supper mode:%d\r\n", mode);
			sum = 0;
			break;
		default :
//					printf("FLAG ERROR\r\n");
			break;
	}
}


#endif	
/**************************************************************************
函数功能：串口3初始化
入口参数： bound:波特率
返回  值：无
**************************************************************************/
void usart3_init(u32 bound)
{  	 
	  //GPIO端口设置
  NVIC_InitTypeDef NVIC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	//使能UGPIOB时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);	//使能USART3时钟
	//USART3_TX  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB.10
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
  GPIO_Init(GPIOB, &GPIO_InitStructure);
   
  //USART3_RX	  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PB11
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOB, &GPIO_InitStructure);

   //USART 初始化设置
	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
  USART_Init(USART3, &USART_InitStructure);     //初始化串口3
  USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启串口接受中断
  USART_Cmd(USART3, ENABLE);                    //使能串口3 
	
	NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		//
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器USART1
}


//串口3,printf 函数
//确保一次发送数据不超过USART3_MAX_SEND_LEN字节
void u3_printf(char* fmt,...)  
{  
	u16 i,j;
	va_list ap;
	va_start(ap,fmt);
	vsprintf((char*)USART3_TX_BUF,fmt,ap);
	va_end(ap);
	i=strlen((const char*)USART3_TX_BUF);//此次发送数据的长度
//	USART_GetFlagStatus(USART3,USART_FLAG_TC);//避免串口3丢失前几位
	for(j=0;j<i;j++)//循环发送数据
	{
		USART_SendData(USART3,USART3_TX_BUF[j]); 	 //发送数据到串口3 
		USART_SendData(USART1,USART3_TX_BUF[j]); 	 //发送数据到串口3 
		while(USART_GetFlagStatus(USART3,USART_FLAG_TC)!=SET);//等待发送结束
	}
	
}
